<?php

declare (strict_types=1);
namespace App\Model;

use App\Cache\CacheKey;
use App\Tool\SensitiveFilter;
use Carbon\Carbon;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Events\Saved;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;

/**
 * @property int $id 
 * @property int $user_id 作者ID
 * @property string $title 标题
 * @property string $slug URL标识
 * @property string $content 内容
 * @property ?string $summary 摘要
 * @property string $content_type 内容类型
 * @property string $cover_image 封面图
 * @property string $status 状态
 * @property int $view_count 浏览数
 * @property int $like_count 点赞数
 * @property int $comment_count 评论数
 * @property int $favorite_count 收藏数
 * @property int $reading_time 阅读时长(分钟)
 * @property ?Carbon $published_at 发布时间
 * @property  string $password
 * @property Carbon $created_at
 * @property Carbon $updated_at
 *
 * @property-read User $user
 * @property-read Collection<Comment> $comments
 * @property-read Collection<Category> $categories
 */
class Article extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'articles';
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['id', 'user_id', 'title', 'slug', 'content', 'summary', 'content_type', 'cover_image', 'status', 'view_count', 'like_count', 'comment_count', 'favorite_count', 'reading_time', 'published_at', 'created_at', 'updated_at'];
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = ['id' => 'integer', 'user_id' => 'integer', 'view_count' => 'integer', 'like_count' => 'integer', 'comment_count' => 'integer', 'favorite_count' => 'integer', 'reading_time' => 'integer', 'published_at' => 'datetime', 'created_at' => 'datetime', 'updated_at' => 'datetime'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function categories()
    {
        return $this->belongsToMany(Category::class);
    }

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }

    public function saved(Saved $event)
    {
        $redis = ApplicationContext::getContainer()->get(Redis::class);
        /**@var self $model*/
        $model = $event->getModel();
        $id = $model->getKey();

        $md5 = $redis->hGet(CacheKey::articleSensitiveWords($id), 'md5');
        if ($md5 === md5($model->content)) {
            return ;
        }

        $filter = new SensitiveFilter(config('sensitive_words'));
        $result = $filter->analyzeText($model->content);
        $redis->hMSet(CacheKey::articleSensitiveWords($id), [
            'md5' => md5($model->content),
            'original_text' => $result['original_text'],
            'sensitive_positions' => $result['sensitive_positions'],
            'marked_html' => $result['marked_html'],
            'sensitive_words' => $result['sensitive_words'],
        ]);
    }
}